<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { FolderYellow, Top, Refresh } from '@/util/icons'
import Scrollbar from '@/components/Scrollbar.vue'
import type { Page } from '@/types'
import type { FileTable } from '@/types/file'
import { getFileList } from '../views/sys/file/api'
import { dateFormat, getFormatDictMap } from '@/util/dict'
import FileIcon from '../views/sys/file/FileIcon.vue'
import Pagination from '@/components/Pagination.vue'
import { deepCopy } from '@/util/token'

/**
 * 传入
 */
const prop = defineProps<{
  fType?: 'dir' | 'file' // 是否只查询某文件类型
  pKey?: string // 父组件希望携带的关键字
}>()
/**
 * 选择事件
 */
const emit = defineEmits<{
  (
    e: 'select',
    data: {
      id: number
      path: string
      name: string
      pKey: string
    }
  ): void
}>()
/* 获取对应的字典信息 */
const tableDict = ref<Map<string, string>>()
const statusDict = ref<Map<string, string>>()
const page = ref<Page<FileTable>>({
  num: 1,
  size: 50,
  rows: [],
  count: 0
})
const loading = ref<boolean>(false)
const parentList = ref<FileTable[]>([])
/* 搜索 */
/* 是否展示搜索栏 */
const searchForm = ref<FileTable>({
  name: '',
  parent: 0,
  fType: prop.fType!
})
// 获取页面数据
function getPageData() {
  if (loading.value) {
    return
  }
  loading.value = true
  let data: any
  getFileList(page.value, searchForm.value)
    .then((d) => {
      data = d.data
    })
    .finally(() => {
      setTimeout(() => {
        page.value = data as Page<FileTable>
        loading.value = false
      }, 100)
    })
}

/* 数据选择器 */
const selectData = ref<FileTable[]>([])
function onSelect(data: FileTable[]) {
  selectData.value = data
}
onMounted(() => {
  getFormatDictMap('sys_file', 'head').then((d) => {
    tableDict.value = d
  })
  getFormatDictMap('sys_file_status', 'val').then((d) => {
    statusDict.value = d
  })
  getPageData()
})

// 返回上一级目录
function back() {
  let file = parentList.value.pop()
  searchForm.value.parent = file?.parent
  getPageData()
}

// 去到某个目录
function go(fId: number) {
  searchForm.value.parent = fId
  if (fId == 0) {
    parentList.value = []
  } else {
    let index = 1
    for (let item of parentList.value) {
      if (item.id == fId) {
        break
      }
      index++
    }
    parentList.value.splice(index)
  }
  getPageData()
}

// 打开文件夹
function openFolder(file: FileTable) {
  if (file.fType !== 'dir') {
    return
  }
  parentList.value.push(deepCopy(file))
  searchForm.value.parent = file.id
  getPageData()
}

function selectFile(file: FileTable) {
  emit('select', {
    name: file.name!,
    id: file.id!,
    path: file.path!,
    pKey: prop.pKey || ''
  })
}
</script>
<template>
  <div class="file-select">
    <div class="header">
      <el-row style="width: 65%; min-width: 500px">
        <el-col :span="3">
          <el-button
            class="up-button"
            @click="back"
            :icon="Top"
            :round="false"
            :disabled="parentList.length == 0"
          />
        </el-col>
        <el-col :span="18">
          <div class="path">
            <span class="path-item path-root" @click="go(0)">根目录</span>
            <span class="path-item" v-for="item in parentList" @click="go(item.id!)">
              / {{ item.name }}
            </span>
          </div>
        </el-col>
        <el-col :span="3"
          ><el-button @click="getPageData" :icon="Refresh" class="up-button"
        /></el-col>
      </el-row>
    </div>
    <div class="ctx">
      <Scrollbar>
        <el-table
          v-loading="loading"
          :data="page.rows"
          table-layout="auto"
          :stripe="true"
          row-key="id"
          @selection-change="onSelect"
        >
          <el-table-column type="selection" width="50" />
          <el-table-column min-width="300">
            <template #header>
              {{ tableDict?.get('name') || 'name' }}
            </template>
            <template #default="{ row }">
              <div class="info-row" @click="openFolder(row)">
                <span class="icon"
                  ><FolderYellow v-if="row['fType'] == 'dir'" />
                  <el-icon v-else>
                    <FileIcon :suffix="row['suffix']" />
                  </el-icon>
                </span>
                <span>{{ row.name }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column width="150px" align="center">
            <template #header>
              {{ tableDict?.get('createTime') || 'createTime' }}
            </template>
            <template #default="{ row }">
              <span>{{ dateFormat(row.createTime) }}</span>
            </template>
          </el-table-column>
          <el-table-column width="150px" align="center">
            <template #header>
              {{ tableDict?.get('createBy') || 'createBy' }}
            </template>
            <template #default="{ row }">
              <span>{{ row.createBy }}</span>
            </template>
          </el-table-column>
          <el-table-column width="400px" align="center">
            <template #header> 操作 </template>
            <template #default="{ row }">
              <span class="buttons">
                <el-button type="warning" @click="selectFile(row)"> 选择 </el-button>
              </span>
            </template>
          </el-table-column>
        </el-table>
      </Scrollbar>
    </div>
    <div class="footer">
      <Pagination :page="page" :get-page-data="getPageData" />
    </div>
  </div>
</template>
<style scoped lang="less">
@header-height: 60px;
@control-height: 40px;
@footer-height: 60px;
@path-header: 40px;
.header {
  height: @header-height;
  color: var(--el-color-info);

  .up-button {
    height: @path-header;
    width: 100%;
    font-size: 30px;
    border-radius: 0;
  }
  .path-root {
    margin-left: 20px;
  }
  .path {
    height: @path-header;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    vertical-align: middle;
    border: var(--el-border);
    border-right: none;
    border-left: none;
    line-height: @path-header - 2px;
  }
  .path-item {
    margin-right: 10px;
    cursor: pointer;
    &:hover {
      background: aliceblue;
    }
  }
}
.ctx {
  height: calc(100% - @footer-height - @header-height - @control-height);
}
.footer {
  height: @footer-height;
  box-sizing: border-box;
  padding: 1px;
}
.info-row {
  height: 40px;
  display: flex;
  align-items: center;
  cursor: pointer;
  .icon {
    font-size: 30px;
    margin-right: 10px;
  }
  & > span {
    top: 0;
    line-height: 40px;
    height: 40px;
    display: inline-block;
  }
}
</style>
